package com.smartleanx.module.hrm.app.empRisk;

import cn.hutool.core.collection.CollUtil;
import com.smartleanx.framework.common.enums.BizTypeEnum;
import com.smartleanx.framework.common.util.collection.CollectionUtils;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeDO;
import com.smartleanx.module.hrm.dal.dataobject.employee.EmployeeSeparationRecordDO;
import com.smartleanx.module.hrm.dal.dataobject.risk.RiskTypeDO;
import com.smartleanx.module.hrm.enums.ErrorCodeConstants;
import com.smartleanx.module.hrm.eums.employee.BizFileTypeEnum;
import com.smartleanx.module.hrm.eums.employee.EmployeeRecordTypeEnum;
import com.smartleanx.module.hrm.eums.risk.RiskLevelEnum;
import com.smartleanx.module.hrm.eums.risk.RiskTypeEnum;
import com.smartleanx.module.hrm.intergration.FileServiceProvider;
import com.smartleanx.module.hrm.service.employee.EmployeeSeparationRecordService;
import com.smartleanx.module.hrm.service.employee.EmployeeService;
import com.smartleanx.module.hrm.service.risk.RiskService;
import com.smartleanx.module.infra.api.file.dto.FileRefQueryDTO;
import com.smartleanx.module.infra.api.file.dto.FileRefRespDTO;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static com.smartleanx.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 工作交接表
 *
 * @author tengcj
 * @since 2024/6/11
 */
@Component
public class RiskWorkHandoverFormHandleService implements EmployeeRiskHandle {

    @Resource
    private EmployeeService employeeService;

    @Resource
    private EmployeeSeparationRecordService employeeSeparationRecordService;

    @Resource
    private FileServiceProvider fileServiceProvider;

    @Resource
    private RiskService riskService;

    public static final long RISK_ID = RiskTypeEnum.WORK_HANDOVER_FORM.getCode();

    @Override
    public Long type() {
        return RISK_ID;
    }

    @Override
    public void handleEmployeeRisk(Set<Long> employeeIds) {
        List<EmployeeDO> employeeList = employeeService.getEmployeeList(employeeIds);
        if (CollUtil.isEmpty(employeeList)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }
        RiskTypeDO riskType = riskService.getRiskType(RISK_ID);
        if (riskType == null) {
            throw exception(ErrorCodeConstants.RISK_TYPE_NOT_EXISTS);
        }

        List<EmployeeSeparationRecordDO> separationRecordList = employeeSeparationRecordService.getSeparationRecordList(employeeIds)
                        .stream().filter(
                                record -> Objects.equals(EmployeeRecordTypeEnum.Management.getType(), record.getCreateType())
                ).collect(Collectors.toList());
        Set<Long> recordIdList = separationRecordList.stream().map(EmployeeSeparationRecordDO::getId).collect(Collectors.toSet());

        if (CollUtil.isEmpty(recordIdList)) {
            riskService.deleteRisk(employeeIds, RISK_ID);
            return;
        }

        // 离职申请表单
        FileRefQueryDTO fileRefQueryDTO = new FileRefQueryDTO();
        fileRefQueryDTO.setBizType(BizTypeEnum.EMPLOYEE_LEAVE.getValue());
        fileRefQueryDTO.setBizFileTypes(Collections.singletonList(BizFileTypeEnum.WORK_HANDOVER.getCode()));
        fileRefQueryDTO.setBizRecordIds(recordIdList);
        List<FileRefRespDTO> fileRefList = fileServiceProvider.getFileRef(fileRefQueryDTO);
        Map<Long, FileRefRespDTO> fileRefMap = CollectionUtils.convertMap(fileRefList, FileRefRespDTO::getBizRecordId);

        Map<Long, List<EmployeeSeparationRecordDO>> recordMap = CollectionUtils.convertMultiMap(
                separationRecordList, EmployeeSeparationRecordDO::getEmployeeId
        );

        // 员工材料附件
        FileRefQueryDTO empFileRefQueryDTO = new FileRefQueryDTO();
        empFileRefQueryDTO.setBizType(BizTypeEnum.EMPLOYEE.getValue());
        empFileRefQueryDTO.setBizFileTypes(Collections.singletonList(BizFileTypeEnum.WORK_HANDOVER.getCode()));
        empFileRefQueryDTO.setBizRecordIds(employeeIds);
        List<FileRefRespDTO> empFileRefList = fileServiceProvider.getFileRef(empFileRefQueryDTO);
        Map<Long, FileRefRespDTO> empFileRefMap = CollectionUtils.convertMap(empFileRefList, FileRefRespDTO::getBizRecordId);

        for (EmployeeDO employeeDO : employeeList) {
            List<EmployeeSeparationRecordDO> recordList = recordMap.get(employeeDO.getId());
            if (CollUtil.isEmpty(recordList)) {
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }
            // 如果在员工材料附件上传则消除风险
            if (empFileRefMap.get(employeeDO.getId()) != null) {
                riskService.deleteRisk(employeeDO.getId(), RISK_ID);
                continue;
            }
            for (EmployeeSeparationRecordDO recordDO : recordList) {
                if (fileRefMap.get(recordDO.getId()) == null) {
                    riskService.addRisk(employeeDO.getId(), RISK_ID, RiskLevelEnum.MAJOR.getLevel(), recordDO.getId());
                } else {
                    riskService.deleteRisk(employeeDO.getId(), RISK_ID, recordDO.getId());
                }
            }
        }
    }

}
